/**
 * LLM服务 - 专门处理与大模型的通信
 * 松耦合设计，简化错误处理，减少嵌套
 */

// 默认系统提示词
const DEFAULT_SYSTEM_PROMPTS = [
  { role: 'system', content: '#你所有的回答都是JSON格式【你所有的回答都是JSON格式】' },
  { role: 'system', content: '不要多余解释！单选题多选题和判断题只要答案的选项即可（单选题answer字段是只有一个元素的数组，多选题answer字段是数组，判断题数组元素是正确或者是错误）,最终输出格式为:{ "answer": ["A","*"]  }' },
  { role: 'system', content: '不要多余解释！填空题一个问题可能有多个空要确保，一个填空标志为▁▁▁▁▁，或者识别填空项1,填空项2,填空项3...作为最终数组的length，不要多出数组！答案是数组{ "answer": ["填空答案一","二"]  }' }
]

/**
 * 流式请求大模型
 * @param {Object} options - 请求参数
 * @param {string} options.text - 用户问题文本
 * @param {Object} options.config - 配置信息
 * @param {Function} options.onContent - 内容回调
 * @param {Function} options.onError - 错误回调
 * @param {Function} options.onComplete - 完成回调
 * @returns {Promise<string>} - 完整响应文本
 */
export async function streamRequest({
  text,
  config,
  onContent = () => {},
  onError = () => {},
  onComplete = () => {}
}) {
  // 参数检查
  if (!text) {
    const error = new Error('缺少请求文本')
    onError(error)
    return ''
  }

  // 提取配置
  const appConfig = config?.appConfig || {}
  const modelConfig = config?.modelConfig || {}
  const apiKey = modelConfig.apiKey
  const baseUrl = modelConfig.baseUrl || 'https://api.siliconflow.cn/v1/chat/completions'
  
  // 验证API密钥
  if (!apiKey) {
    const error = new Error('未配置API密钥')
    onError(error)
    return ''
  }

  // 准备请求体
  const messages = [
    ...(appConfig.messages || DEFAULT_SYSTEM_PROMPTS),
    { role: 'user', content: text }
  ]
  
  const model = appConfig.extraConfig?.model || 'Qwen/Qwen2.5-7B-Instruct'
  const temperature = appConfig.extraConfig?.temperature || 0.3
  const top_p = appConfig.extraConfig?.top_p || 0.9
  
  const payload = { model, messages, stream: true, temperature, top_p }
  
  try {
    // 发送请求
    const response = await fetch(baseUrl, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    })

    // 检查响应状态
    if (!response.ok) {
      const errorText = await response.text()
      throw new Error(`API请求失败: ${response.status} ${response.statusText} - ${errorText}`)
    }

    if (!response.body) {
      throw new Error('API响应没有内容')
    }

    // 处理流式响应
    return await processStream(response.body, onContent, onError, onComplete)
  } catch (error) {
    onError(error)
    return ''
  }
}

/**
 * 处理流式响应
 * @param {ReadableStream} stream - 响应流
 * @param {Function} onContent - 内容回调
 * @param {Function} onError - 错误回调
 * @param {Function} onComplete - 完成回调
 * @returns {Promise<string>} - 完整响应文本
 */
async function processStream(stream, onContent, onError, onComplete) {
  const reader = stream.getReader()
  const decoder = new TextDecoder('utf-8')
  let buffer = ''
  let result = ''

  try {
    while (true) {
      // 读取数据块
      const { value, done } = await reader.read()
      
      // 流结束检查
      if (done) break
      
      // 解码数据块
      const chunk = decoder.decode(value, { stream: true })
      buffer += chunk
      
      // 按行处理数据
      const lines = buffer.split('\n')
      buffer = lines.pop() || ''
      
      // 处理每一行
      for (const line of lines) {
        const trimmedLine = line.trim()
        
        // 跳过非数据行
        if (!trimmedLine.startsWith('data: ')) continue
        
        // 提取JSON字符串
        const jsonStr = trimmedLine.slice(6).trim()
        if (!jsonStr || jsonStr === '[DONE]') continue
        
        // 解析JSON
        try {
          const parsed = JSON.parse(jsonStr)
          
          // 提取内容
          if (parsed.choices && parsed.choices.length > 0) {
            for (const choice of parsed.choices) {
              if (!choice || !choice.delta) continue
              
              const content = choice.delta.content
              if (content) {
                // 累加结果
                result += content
                // 回调通知
                onContent(content, result)
              }
            }
          }
        } catch (err) {
          console.error('JSON解析错误:', err)
        }
      }
    }
    
    // 完成回调
    onComplete(result)
    return result
  } catch (error) {
    onError(error)
    return result
  } finally {
    // 确保释放资源
    reader.releaseLock()
  }
}

/**
 * 测试API连接
 * @param {Object} config - 配置信息
 * @returns {Promise<Object>} - 连接测试结果
 */
export async function testConnection(config) {
  const modelConfig = config?.modelConfig
  const appConfig = config?.appConfig
  
  if (!modelConfig || !modelConfig.apiKey) {
    throw new Error('未配置API密钥')
  }
  
  const url = modelConfig.baseUrl || 'https://api.siliconflow.cn/v1/chat/completions'
  const model = appConfig?.extraConfig?.model || 'Qwen/Qwen2.5-7B-Instruct'
  
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${modelConfig.apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      model,
      messages: [{ role: 'user', content: '测试连接' }],
      max_tokens: 5
    })
  })
  
  if (!response.ok) {
    const errorText = await response.text()
    throw new Error(`API连接测试失败: ${response.status} ${response.statusText} - ${errorText}`)
  }
  
  return { status: 'connected', url }
}

/**
 * 从文本中提取完整JSON对象
 * @param {string} text - 包含JSON对象的文本
 * @returns {string|null} - 完整的JSON字符串或null
 */
export function extractJSON(text) {
  if (!text) return null
  
  const firstBrace = text.indexOf('{')
  if (firstBrace === -1) return null
  
  let braceCount = 0
  let jsonStr = ''
  let started = false
  
  for (let i = 0; i < text.length; i++) {
    const char = text[i]
    
    if (char === '{' && !started) {
      started = true
      braceCount = 1
      jsonStr += char
    } else if (started) {
      jsonStr += char
      
      if (char === '{') {
        braceCount++
      } else if (char === '}') {
        braceCount--
        
        if (braceCount === 0) {
          return jsonStr
        }
      }
    }
  }
  
  return null
} 